package nerdicide.experiments.reasoning;

import java.util.ArrayList;
import java.util.HashMap;

import nerdicide.utils.XMLModel;

/**
 * 
 * @author Brent Kersanske
 *
 */
public class MultipleChoiceQuestion {
	
	private static final String MULTIPLE_CHOICE_QUESTION = "multipleChoiceQuestion";
	private static final String FORM			    = "form";
	public static final String PLAIN_FORM 			= "pf";
	public static final String UNFAMILIAR_VERB_FORM = "ufVerb";
	public static final String UNFAMILIAR_NOUN_FORM = "ufNoun";
	
	private static final String SCENARIO = "scenario";
	private static final String QUESTION = "question";
	private static final String OPTION   = "option";
	private static final String OPTIONS  = "options";
	private static final String ID		 = "id";
	private static final String VALUE	 = "value";
	
	private String questionNumber;
	private String scenario;
	private String formattedScenario;
	private String question;
	private String formattedQuestion;
	private String correctOption;
	private ArrayList<String> answerOptions;
	private ArrayList<String> formattedOptions;
	private HashMap<String, String> plainNouns;
	private HashMap<String, String> plainVerbs;
	private HashMap<String, String> unfamiliarNouns;
	private HashMap<String, String> unfamiliarVerbs;
	
	/**
	 * Constructor.
	 * @param scenario
	 * @param question
	 * @param optionA
	 * @param optionB
	 * @param optionC
	 * @param optionD
	 * @param optionE
	 */
	public MultipleChoiceQuestion(int number, String scenario, String question, String correctOption, ArrayList<String> answerOptions, HashMap<String, String> plainNouns, HashMap<String, String> plainVerbs) {
		this.questionNumber   = String.valueOf(number);
		this.scenario         = scenario;
		this.question         = question;
		this.correctOption    = correctOption;
		this.answerOptions    = answerOptions;
		this.plainNouns	      = plainNouns;
		this.plainVerbs       = plainVerbs;
		this.unfamiliarNouns  = UnfamiliarWordPool.generateUnfamiliarNounMap(plainNouns.size());
		this.unfamiliarVerbs  = UnfamiliarWordPool.generateUnfamiliarVerbMap(this.plainVerbs.size());
		resetFormattedStrings();
	}

	@SuppressWarnings("unchecked")
	private void resetFormattedStrings() {
		this.formattedScenario = String.copyValueOf(scenario.toCharArray());
		this.formattedQuestion = String.copyValueOf(question.toCharArray());
		this.formattedOptions = ((ArrayList<String>)this.answerOptions.clone());
	}
	
	/**
	 * 
	 * @param words
	 */
	private void swapInWords(HashMap<String, String> words) {
		for(String encoding : words.keySet()) {
			this.formattedScenario = this.formattedScenario.replace(encoding, words.get(encoding));
			this.formattedQuestion = this.formattedQuestion.replace(encoding, words.get(encoding));
			for(int i = 0; i < this.formattedOptions.size(); i++) {
				String option = this.formattedOptions.get(i);
				this.formattedOptions.set(i, option.replace(encoding, words.get(encoding)));
			}
		}
	}	
	
	/**
	 * 
	 * @param rootModel
	 * @return
	 */
	private XMLModel insertFormattedModel(XMLModel rootModel) {
		rootModel.addAttribute(ID, this.questionNumber);
		XMLModel scenarioModel = new XMLModel(SCENARIO);
		scenarioModel.addAttribute(VALUE, this.formattedScenario);
		rootModel.addChildModel(scenarioModel);
		XMLModel questionModel = new XMLModel(QUESTION);
		questionModel.addAttribute(VALUE, this.formattedQuestion);
		rootModel.addChildModel(questionModel);		
		XMLModel optionsModel = new XMLModel(OPTIONS);
		optionsModel.addAttribute("correctOption", this.correctOption);
		for(int i = 0; i < this.formattedOptions.size(); i++) {
			XMLModel optionModel = new XMLModel(OPTION);
			optionModel.addAttribute(ID, String.valueOf(i+1));
			optionModel.addAttribute(VALUE, this.formattedOptions.get(i));
			optionsModel.addChildModel(optionModel);
		}
		rootModel.addChildModel(optionsModel);
		return rootModel;		
	}
	
	/**
	 * 
	 * @return
	 */
	public String getPlainFormModel() {
		resetFormattedStrings();
		swapInWords(plainNouns);
		swapInWords(plainVerbs);
		XMLModel pfModel    = new XMLModel(MULTIPLE_CHOICE_QUESTION);
		pfModel.addAttribute(FORM, PLAIN_FORM);
		XMLModel plainModel = insertFormattedModel(pfModel);
		return plainModel.getModel();
	}
	
	/**
	 * 
	 * @return
	 */
	public String getUnfamiliarVerbFormModel() {
		resetFormattedStrings();
		swapInWords(plainNouns);
		swapInWords(unfamiliarVerbs);
		XMLModel ufvfModel = new XMLModel(MULTIPLE_CHOICE_QUESTION);
		ufvfModel.addAttribute(FORM, UNFAMILIAR_VERB_FORM);
		XMLModel unfamiliarVerbModel = insertFormattedModel(ufvfModel);
		return unfamiliarVerbModel.getModel();
	}
	
	/**
	 * 
	 * @return
	 */
	public String getUnfamiliarNounFormModel() {
		resetFormattedStrings();
		swapInWords(unfamiliarNouns);
		swapInWords(plainVerbs);
		XMLModel ufnfModel = new XMLModel(MULTIPLE_CHOICE_QUESTION);
		ufnfModel.addAttribute(FORM, UNFAMILIAR_NOUN_FORM);
		XMLModel unfamiliarNounModel = insertFormattedModel(ufnfModel);
		return unfamiliarNounModel.getModel();
	}
}
